/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.zlw.main.audioeffects.utils;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.BaseColumns;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/**
 * The Music provider contains meta data for all available media on both internal and external storage
 * devices.
 */
public final class MusicStore {

    public static final String AUTHORITY = "gnmusic";

    private static final String CONTENT_AUTHORITY_SLASH = "content://" + AUTHORITY + "/";

    /**
     * Activity Action: Launch a music player. The activity should be able to play, browse, or manipulate
     * music files stored on the device.
     * 
     * @deprecated Use {@link android.content.Intent#CATEGORY_APP_MUSIC} instead.
     */
    @Deprecated
    public static final String INTENT_ACTION_MUSIC_PLAYER = "android.intent.action.MUSIC_PLAYER";

    /**
     * Activity Action: Perform a search for media. Contains at least the
     * {@link android.app.SearchManager#QUERY} extra. May also contain any combination of the following
     * extras: EXTRA_MEDIA_ARTIST, EXTRA_MEDIA_ALBUM, EXTRA_MEDIA_TITLE, EXTRA_MEDIA_FOCUS
     * 
     * @see android.provider.MusicStore#EXTRA_MEDIA_ARTIST
     * @see android.provider.MusicStore#EXTRA_MEDIA_ALBUM
     * @see android.provider.MusicStore#EXTRA_MEDIA_TITLE
     * @see android.provider.MusicStore#EXTRA_MEDIA_FOCUS
     */
    public static final String INTENT_ACTION_MEDIA_SEARCH = "android.intent.action.MEDIA_SEARCH";

    /**
     * An intent to perform a search for music media and automatically play content from the result when
     * possible. This can be fired, for example, by the result of a voice recognition command to listen to
     * music.
     * <p>
     * Contains the {@link android.app.SearchManager#QUERY} extra, which is a string that can contain any type
     * of unstructured music search, like the name of an artist, an album, a song, a genre, or any combination
     * of these.
     * <p>
     * Because this intent includes an open-ended unstructured search string, it makes the most sense for apps
     * that can support large-scale search of music, such as services connected to an online database of music
     * which can be streamed and played on the device.
     */
    public static final String INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH = "android.media.action.MEDIA_PLAY_FROM_SEARCH";

    /**
     * The name of the Intent-extra used to define the artist
     */
    public static final String EXTRA_MEDIA_ARTIST = "android.intent.extra.artist";
    /**
     * The name of the Intent-extra used to define the album
     */
    public static final String EXTRA_MEDIA_ALBUM = "android.intent.extra.album";
    /**
     * The name of the Intent-extra used to define the song title
     */
    public static final String EXTRA_MEDIA_TITLE = "android.intent.extra.title";
    /**
     * The name of the Intent-extra used to define the search focus. The search focus indicates whether the
     * search should be for things related to the artist, album or song that is identified by the other
     * extras.
     */
    public static final String EXTRA_MEDIA_FOCUS = "android.intent.extra.focus";

    /**
     * The name of the Intent-extra used to control the orientation of a ViewImage or a MovieView. This is an
     * int property that overrides the activity's requestedOrientation.
     * 
     * @see android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
     */
    public static final String EXTRA_SCREEN_ORIENTATION = "android.intent.extra.screenOrientation";

    /**
     * The name of an Intent-extra used to control the UI of a ViewImage. This is a boolean property that
     * overrides the activity's default fullscreen state.
     */
    public static final String EXTRA_FULL_SCREEN = "android.intent.extra.fullScreen";

    /**
     * The name of an Intent-extra used to control the UI of a ViewImage. This is a boolean property that
     * specifies whether or not to show action icons.
     */
    public static final String EXTRA_SHOW_ACTION_ICONS = "android.intent.extra.showActionIcons";

    /**
     * The name of the Intent-extra used to control the onCompletion behavior of a MovieView. This is a
     * boolean property that specifies whether or not to finish the MovieView activity when the movie
     * completes playing. The default value is true, which means to automatically exit the movie player
     * activity when the movie completes playing.
     */
    public static final String EXTRA_FINISH_ON_COMPLETION = "android.intent.extra.finishOnCompletion";

    /**
     * The name of Intent-extra used to control the loop behavoir of a MovieView. This is a boolean property
     * that specifies whether or not to loop the sent uris. If you sent one uri, it will loop one. otheriwise,
     * it will loop the list.
     * 
     * @hide
     */
    public static final String EXTRA_LOOP_PLAYBACK = "android.intent.extra.loopPlayback";

    /**
     * The name of Intent-extra used to tell MovieView to play a list of Uris. It can be used with
     * {@link MusicStore#EXTRA_LOOP_PLAYBACK}.
     * 
     * @hide
     */
    public static final String EXTRA_URI_LIST = "android.intent.extra.uriList";

    /**
     * The name of the Intent action used to launch a camera in still image mode.
     */
    public static final String INTENT_ACTION_STILL_IMAGE_CAMERA = "android.media.action.STILL_IMAGE_CAMERA";

    /**
     * The name of the Intent action used to launch a camera in video mode.
     */
    public static final String INTENT_ACTION_VIDEO_CAMERA = "android.media.action.VIDEO_CAMERA";

    /**
     * Standard Intent action that can be sent to have the camera application capture an image and return it.
     * <p>
     * The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. If the
     * EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra
     * field. This is useful for applications that only need a small image. If the EXTRA_OUTPUT is present,
     * then the full-sized image will be written to the Uri value of EXTRA_OUTPUT.
     * 
     * @see #EXTRA_OUTPUT
     */
    public final static String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";

    /**
     * Standard Intent action that can be sent to have the camera application capture an video and return it.
     * <p>
     * The caller may pass in an extra EXTRA_VIDEO_QUALITY to control the video quality.
     * <p>
     * The caller may pass in an extra EXTRA_OUTPUT to control where the video is written. If EXTRA_OUTPUT is
     * not present the video will be written to the standard location for videos, and the Uri of that location
     * will be returned in the data field of the Uri.
     * 
     * @see #EXTRA_OUTPUT
     * @see #EXTRA_VIDEO_QUALITY
     * @see #EXTRA_SIZE_LIMIT
     * @see #EXTRA_DURATION_LIMIT
     */
    public final static String ACTION_VIDEO_CAPTURE = "android.media.action.VIDEO_CAPTURE";

    /**
     * The name of the Intent-extra used to control the quality of a recorded video. This is an integer
     * property. Currently value 0 means low quality, suitable for MMS messages, and value 1 means high
     * quality. In the future other quality levels may be added.
     */
    public final static String EXTRA_VIDEO_QUALITY = "android.intent.extra.videoQuality";

    /**
     * Specify the maximum allowed size.
     */
    public final static String EXTRA_SIZE_LIMIT = "android.intent.extra.sizeLimit";

    /**
     * Specify the maximum allowed recording duration in seconds.
     */
    public final static String EXTRA_DURATION_LIMIT = "android.intent.extra.durationLimit";

    /**
     * The name of the Intent-extra used to indicate a content resolver Uri to be used to store the requested
     * image or video.
     */
    public final static String EXTRA_OUTPUT = "output";

    /**
     * The string that is used when a media attribute is not known. For example, if an audio file does not
     * have any meta data, the artist and album columns will be set to this value.
     */
    public static final String UNKNOWN_STRING = AppConsts.UNKNOWN_ARTIST_TAG;//"<unknown>";

    /**
     * Common fields for most MediaProvider tables
     */

    public interface MediaColumns extends BaseColumns, DrmColumns {
        /**
         * The data stream for the file
         * <P>
         * Type: DATA STREAM
         * </P>
         */
        public static final String DATA = "_data";

        /**
         * The size of the file in bytes
         * <P>
         * Type: INTEGER (long)
         * </P>
         */
        public static final String SIZE = "_size";

        /**
         * The display name of the file
         * <P>
         * Type: TEXT
         * </P>
         */
        public static final String DISPLAY_NAME = "_display_name";

        /**
         * The title of the content
         * <P>
         * Type: TEXT
         * </P>
         */
        public static final String TITLE = "title";

        /**
         * The time the file was added to the media provider Units are seconds since 1970.
         * <P>
         * Type: INTEGER (long)
         * </P>
         */
        public static final String DATE_ADDED = "date_added";

        /**
         * The time the file was last modified Units are seconds since 1970. NOTE: This is for internal use by
         * the media scanner. Do not modify this field.
         * <P>
         * Type: INTEGER (long)
         * </P>
         */
        public static final String DATE_MODIFIED = "date_modified";

        /**
         * The MIME type of the file
         * <P>
         * Type: TEXT
         * </P>
         */
        public static final String MIME_TYPE = "mime_type";

        public static final String MEDIA_SCANNER_NEW_OBJECT_ID = "media_scanner_new_object_id";

        /**
         * Non-zero if the media file is drm-protected
         * <P>
         * Type: INTEGER (boolean)
         * </P>
         * 
         * @hide
         */
        public static final String IS_DRM = "is_drm";

        /**
         * The width of the image/video in pixels.
         * 
         * @hide
         */
        public static final String WIDTH = "width";

        /**
         * The height of the image/video in pixels.
         * 
         * @hide
         */
        public static final String HEIGHT = "height";
    }

    /**
     * Media provider table containing an index of all files in the media storage, including non-media files.
     * This should be used by applications that work with non-media file types (text, HTML, PDF, etc) as well
     * as applications that need to work with multiple media file types in a single query.
     */
    public static final class Files {

        /**
         * Get the content:// style URI for the files table on the given volume.
         * 
         * @param volumeName
         *            the name of the volume to get the URI for
         * @return the URI to the files table on the given volume
         */
        public static Uri getContentUri(String volumeName) {
            return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/file");
        }

        /**
         * Get the content:// style URI for a single row in the files table on the given volume.
         * 
         * @param volumeName
         *            the name of the volume to get the URI for
         * @param rowId
         *            the file to get the URI for
         * @return the URI to the files table on the given volume
         */
        public static final Uri getContentUri(String volumeName, long rowId) {
            return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/file/" + rowId);
        }

        /**
         * For use only by the MTP implementation.
         * 
         * @hide
         */
        public static final Uri getMtpObjectsUri(String volumeName, long fileId) {
            return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/object/" + fileId);
        }

        /**
         * Fields for master table for all media files. Table also contains MediaColumns._ID, DATA, SIZE and
         * DATE_MODIFIED.
         */
        public interface FileColumns extends MediaColumns {
            /**
             * The MTP storage ID of the file
             * <P>
             * Type: INTEGER
             * </P>
             * 
             * @hide
             */
            public static final String STORAGE_ID = "storage_id";

            /**
             * The MTP format code of the file
             * <P>
             * Type: INTEGER
             * </P>
             * 
             * @hide
             */
            public static final String FORMAT = "format";

            /**
             * The index of the parent directory of the file
             * <P>
             * Type: INTEGER
             * </P>
             */
            public static final String PARENT = "parent";

            /**
             * The MIME type of the file
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String MIME_TYPE = "mime_type";

            /**
             * The title of the content
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String TITLE = "title";

            /**
             * The media type (audio, video, image or playlist) of the file, or 0 for not a media file
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String MEDIA_TYPE = "media_type";
            // Gionee lilt 2012-11-08 add for CRxx begin
            public static final String FOLDER = "_folder";
            public static final String PLAY_COUNT = "_play_count";
            public static final String BIT_RATE = "bit_rate";
            public static final String IS_FEATURED = "is_featured";
            public static final String COMPILATION = "compilation";
            // Gionee lilt 2012-11-08 add for CRxx end

            /**
             * Constant for the {@link #MEDIA_TYPE} column indicating that file is not an audio, image, video
             * or playlist file.
             */
            public static final int MEDIA_TYPE_NONE = 0;

            /**
             * Constant for the {@link #MEDIA_TYPE} column indicating that file is an image file.
             */
            public static final int MEDIA_TYPE_IMAGE = 1;

            /**
             * Constant for the {@link #MEDIA_TYPE} column indicating that file is an audio file.
             */
            public static final int MEDIA_TYPE_AUDIO = 2;

            /**
             * Constant for the {@link #MEDIA_TYPE} column indicating that file is an video file.
             */
            public static final int MEDIA_TYPE_VIDEO = 3;

            /**
             * Constant for the {@link #MEDIA_TYPE} column indicating that file is an playlist file.
             */
            public static final int MEDIA_TYPE_PLAYLIST = 4;
        }
    }

    /**
     * Contains meta data for all available images.
     */
    public static final class Images {
        public interface ImageColumns extends MediaColumns {
            /**
             * The description of the image
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String DESCRIPTION = "description";

            /**
             * The picasa id of the image
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String PICASA_ID = "picasa_id";

            /**
             * Whether the video should be published as public or private
             * <P>
             * Type: INTEGER
             * </P>
             */
            public static final String IS_PRIVATE = "isprivate";

            /**
             * The latitude where the image was captured.
             * <P>
             * Type: DOUBLE
             * </P>
             */
            public static final String LATITUDE = "latitude";

            /**
             * The longitude where the image was captured.
             * <P>
             * Type: DOUBLE
             * </P>
             */
            public static final String LONGITUDE = "longitude";

            /**
             * The date & time that the image was taken in units of milliseconds since jan 1, 1970.
             * <P>
             * Type: INTEGER
             * </P>
             */
            public static final String DATE_TAKEN = "datetaken";

            /**
             * The orientation for the image expressed as degrees. Only degrees 0, 90, 180, 270 will work.
             * <P>
             * Type: INTEGER
             * </P>
             */
            public static final String ORIENTATION = "orientation";

            /**
             * The mini thumb id.
             * <P>
             * Type: INTEGER
             * </P>
             */
            public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";

            /**
             * The bucket id of the image. This is a read-only property that is automatically computed from
             * the DATA column.
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String BUCKET_ID = "bucket_id";

            /**
             * The bucket display name of the image. This is a read-only property that is automatically
             * computed from the DATA column.
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
        }

        public static final class Media implements ImageColumns {
            public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) {
                return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER);
            }

            public static final Cursor query(ContentResolver cr, Uri uri, String[] projection, String where,
                                             String orderBy) {
                return cr.query(uri, projection, where, null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
            }

            public static final Cursor query(ContentResolver cr, Uri uri, String[] projection,
                                             String selection, String[] selectionArgs, String orderBy) {
                return cr.query(uri, projection, selection, selectionArgs,
                        orderBy == null ? DEFAULT_SORT_ORDER : orderBy);
            }

            /**
             * Retrieves an image for the given url as a {@link Bitmap}.
             * 
             * @param cr
             *            The content resolver to use
             * @param url
             *            The url of the image
             * @throws FileNotFoundException
             * @throws IOException
             */
            public static final Bitmap getBitmap(ContentResolver cr, Uri url) throws FileNotFoundException,
                    IOException {
                InputStream input = cr.openInputStream(url);
                Bitmap bitmap = BitmapFactory.decodeStream(input);
                input.close();
                return bitmap;
            }

            /**
             * Get the content:// style URI for the image media table on the given volume.
             * 
             * @param volumeName
             *            the name of the volume to get the URI for
             * @return the URI to the image media table on the given volume
             */
            public static Uri getContentUri(String volumeName) {
                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/images/media");
            }

            /**
             * The content:// style URI for the internal storage.
             */
            public static final Uri INTERNAL_CONTENT_URI = getContentUri("internal");

            /**
             * The content:// style URI for the "primary" external storage volume.
             */
            public static final Uri EXTERNAL_CONTENT_URI = getContentUri("external");

            /**
             * The MIME type of of this directory of images. Note that each entry in this directory will have
             * a standard image MIME type as appropriate -- for example, image/jpeg.
             */
            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/image";

            /**
             * The default sort order for this table
             */
            public static final String DEFAULT_SORT_ORDER = ImageColumns.BUCKET_DISPLAY_NAME;
        }

        /**
         * This class allows developers to query and get two kinds of thumbnails: MINI_KIND: 512 x 384
         * thumbnail MICRO_KIND: 96 x 96 thumbnail
         */
        public static class Thumbnails implements BaseColumns {
            public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) {
                return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER);
            }

            public static final Cursor queryMiniThumbnails(ContentResolver cr, Uri uri, int kind,
                                                           String[] projection) {
                return cr.query(uri, projection, "kind = " + kind, null, DEFAULT_SORT_ORDER);
            }

            public static final Cursor queryMiniThumbnail(ContentResolver cr, long origId, int kind,
                                                          String[] projection) {
                return cr.query(EXTERNAL_CONTENT_URI, projection, IMAGE_ID + " = " + origId + " AND " + KIND
                        + " = " + kind, null, null);
            }

            /**
             * Get the content:// style URI for the image media table on the given volume.
             * 
             * @param volumeName
             *            the name of the volume to get the URI for
             * @return the URI to the image media table on the given volume
             */
            public static Uri getContentUri(String volumeName) {
                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/images/thumbnails");
            }

            /**
             * The content:// style URI for the internal storage.
             */
            public static final Uri INTERNAL_CONTENT_URI = getContentUri("internal");

            /**
             * The content:// style URI for the "primary" external storage volume.
             */
            public static final Uri EXTERNAL_CONTENT_URI = getContentUri("external");

            /**
             * The default sort order for this table
             */
            public static final String DEFAULT_SORT_ORDER = "image_id ASC";

            /**
             * The data stream for the thumbnail
             * <P>
             * Type: DATA STREAM
             * </P>
             */
            public static final String DATA = "_data";

            /**
             * The original image for the thumbnal
             * <P>
             * Type: INTEGER (ID from Images table)
             * </P>
             */
            public static final String IMAGE_ID = "image_id";

            /**
             * The kind of the thumbnail
             * <P>
             * Type: INTEGER (One of the values below)
             * </P>
             */
            public static final String KIND = "kind";

            public static final int MINI_KIND = 1;
            public static final int FULL_SCREEN_KIND = 2;
            public static final int MICRO_KIND = 3;
            /**
             * The blob raw data of thumbnail
             * <P>
             * Type: DATA STREAM
             * </P>
             */
            public static final String THUMB_DATA = "thumb_data";

            /**
             * The width of the thumbnal
             * <P>
             * Type: INTEGER (long)
             * </P>
             */
            public static final String WIDTH = "width";

            /**
             * The height of the thumbnail
             * <P>
             * Type: INTEGER (long)
             * </P>
             */
            public static final String HEIGHT = "height";
        }
    }

    /**
     * Container for all audio content.
     */
    public static final class Audio {
        /**
         * Columns for audio file that show up in multiple tables.
         */
        public interface AudioColumns extends MediaColumns {

            /**
             * Indicates the DURATION is accurate or not.
             * <P>
             * Type: INTEGER (boolean)
             * </P>
             * 
             * @hide
             */
            public static final String IS_ACCURATE_DURATION = "isaccurateduration";
            /**
             * A non human readable key calculated from the TITLE, used for searching, sorting and grouping
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String TITLE_KEY = "title_key";

            /**
             * The duration of the audio file, in ms
             * <P>
             * Type: INTEGER (long)
             * </P>
             */
            public static final String DURATION = "duration";

            /**
             * The position, in ms, playback was at when playback for this file was last stopped.
             * <P>
             * Type: INTEGER (long)
             * </P>
             */
            public static final String BOOKMARK = "bookmark";

            /**
             * The id of the artist who created the audio file, if any
             * <P>
             * Type: INTEGER (long)
             * </P>
             */
            public static final String ARTIST_ID = "artist_id";

            /**
             * The artist who created the audio file, if any
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String ARTIST = "artist";

            /**
             * The artist credited for the album that contains the audio file
             * <P>
             * Type: TEXT
             * </P>
             * 
             * @hide
             */
            public static final String ALBUM_ARTIST = "album_artist";

            /**
             * Whether the song is part of a compilation
             * <P>
             * Type: TEXT
             * </P>
             * 
             * @hide
             */
            public static final String COMPILATION = "compilation";

            /**
             * A non human readable key calculated from the ARTIST, used for searching, sorting and grouping
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String ARTIST_KEY = "artist_key";

            /**
             * The composer of the audio file, if any
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String COMPOSER = "composer";

            /**
             * The id of the album the audio file is from, if any
             * <P>
             * Type: INTEGER (long)
             * </P>
             */
            public static final String ALBUM_ID = "album_id";

            /**
             * The album the audio file is from, if any
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String ALBUM = "album";

            /**
             * A non human readable key calculated from the ALBUM, used for searching, sorting and grouping
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String ALBUM_KEY = "album_key";

            /**
             * The track number of this song on the album, if any. This number encodes both the track number
             * and the disc number. For multi-disc sets, this number will be 1xxx for tracks on the first
             * disc, 2xxx for tracks on the second disc, etc.
             * <P>
             * Type: INTEGER
             * </P>
             */
            public static final String TRACK = "track";

            /**
             * The year the audio file was recorded, if any
             * <P>
             * Type: INTEGER
             * </P>
             */
            public static final String YEAR = "year";

            /**
             * Non-zero if the audio file is music
             * <P>
             * Type: INTEGER (boolean)
             * </P>
             */
            public static final String IS_MUSIC = "is_music";

            /**
             * Non-zero if the audio file is a podcast
             * <P>
             * Type: INTEGER (boolean)
             * </P>
             */
            public static final String IS_PODCAST = "is_podcast";

            /**
             * Non-zero if the audio file may be a ringtone
             * <P>
             * Type: INTEGER (boolean)
             * </P>
             */
            public static final String IS_RINGTONE = "is_ringtone";

            /**
             * Non-zero if the audio file may be an alarm
             * <P>
             * Type: INTEGER (boolean)
             * </P>
             */
            public static final String IS_ALARM = "is_alarm";

            /**
             * Non-zero if the audio file may be a notification sound
             * <P>
             * Type: INTEGER (boolean)
             * </P>
             */
            public static final String IS_NOTIFICATION = "is_notification";

            /**
             * The genre of the audio file, if any
             * <P>
             * Type: TEXT
             * </P>
             * Does not exist in the database - only used by the media scanner for inserts.
             * 
             * @hide
             */
            public static final String GENRE = "genre";

            // Gionee lilt 2012-11-08 add for CRxx begin
            public static final String FOLDER = "_folder";
            public static final String PLAY_COUNT = "_play_count";
            public static final String BIT_RATE = "bit_rate";
            public static final String IS_FEATURED = "is_featured";
            // Gionee lilt 2012-11-08 add for CRxx end
        }

        /**
         * Converts a name to a "key" that can be used for grouping, sorting and searching. The rules that
         * govern this conversion are: - remove 'special' characters like ()[]'!?., - remove leading/trailing
         * spaces - convert everything to lowercase - remove leading "the ", "an " and "a " - remove trailing
         * ", the|an|a" - remove accents. This step leaves us with CollationKey data, which is not human
         * readable
         * 
         * @param name
         *            The artist or album name to convert
         * @return The "key" for the given name.
         */
        public static String keyFor(String name) {
            if (name != null) {
                boolean sortfirst = false;
                if (name.equals(UNKNOWN_STRING)) {
                    return "\001";
                }
                // Check if the first character is \001. We use this to
                // force sorting of certain special files, like the silent ringtone.
                if (name.startsWith("\001")) {
                    sortfirst = true;
                }
                name = name.trim().toLowerCase();
                if (name.startsWith("the ")) {
                    name = name.substring(4);
                }
                if (name.startsWith("an ")) {
                    name = name.substring(3);
                }
                if (name.startsWith("a ")) {
                    name = name.substring(2);
                }
                if (name.endsWith(", the") || name.endsWith(",the") || name.endsWith(", an")
                        || name.endsWith(",an") || name.endsWith(", a") || name.endsWith(",a")) {
                    name = name.substring(0, name.lastIndexOf(','));
                }
                name = name.replaceAll("[\\[\\]\\(\\)\"'.,?!]", "").trim();
                if (name.length() > 0) {
                    // Insert a separator between the characters to avoid
                    // matches on a partial character. If we ever change
                    // to start-of-word-only matches, this can be removed.
                    StringBuilder b = new StringBuilder();
                    b.append('.');
                    int nl = name.length();
                    for (int i = 0; i < nl; i++) {
                        b.append(name.charAt(i));
                        b.append('.');
                    }
                    name = b.toString();
                    String key = DatabaseUtils.getCollationKey(name);
                    if (sortfirst) {
                        key = "\001" + key;
                    }
                    return key;
                } else {
                    return "";
                }
            }
            return null;
        }

        public static final class Media implements AudioColumns {
            /**
             * Get the content:// style URI for the audio media table on the given volume.
             * 
             * @param volumeName
             *            the name of the volume to get the URI for
             * @return the URI to the audio media table on the given volume
             */
            public static Uri getContentUri(String volumeName) {
                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/audio/media");
            }

            public static Uri getDownloadContentUri(String volumeName) {
                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/audio/download");
            }

            public static Uri getContentUriForPath(String path) {
                return (path.startsWith(Environment.getExternalStorageDirectory().getPath()) ? EXTERNAL_CONTENT_URI
                        : INTERNAL_CONTENT_URI);
            }

            /**
             * The content:// style URI for the internal storage.
             */
            public static final Uri INTERNAL_CONTENT_URI = getContentUri("internal");

            /**
             * The content:// style URI for the "primary" external storage volume.
             */
            public static final Uri EXTERNAL_CONTENT_URI = getContentUri("external");

            /**
             * The MIME type for this table.
             */
            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/audio";

            /**
             * The default sort order for this table
             */
            public static final String DEFAULT_SORT_ORDER = TITLE_KEY;

            /**
             * Activity Action: Start SoundRecorder application.
             * <p>
             * Input: nothing.
             * <p>
             * Output: An uri to the recorded sound stored in the Media Library if the recording was
             * successful. May also contain the extra EXTRA_MAX_BYTES.
             * 
             * @see #EXTRA_MAX_BYTES
             */
            public static final String RECORD_SOUND_ACTION = "android.provider.MusicStore.RECORD_SOUND";

            /**
             * The name of the Intent-extra used to define a maximum file size for a recording made by the
             * SoundRecorder application.
             * 
             * @see #RECORD_SOUND_ACTION
             */
            public static final String EXTRA_MAX_BYTES = "android.provider.MusicStore.extra.MAX_BYTES";
        }

        // Gionee <huangwf><2013-3-23> modify for CR00788325 begin
        public interface AlbumArtClumns {
            public static final String ALBUM_ID = "album_id";
            public static final String DATA = "_data";
        }

        public static final class AlbumArt implements BaseColumns, AlbumArtClumns {
            public static final Uri EXTERNAL_CONTENT_URI = getContentUri("external");

            public static Uri getContentUri(String volumeName) {
                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/audio/albumart");
            }
        }
        // Gionee <huangwf><2013-3-23> modify for CR00788325 end

        /**
         * Columns representing an audio genre
         */
        public interface GenresColumns {
            /**
             * The name of the genre
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String NAME = "name";
        }

        /**
         * Contains all genres for audio files
         */
        public static final class Genres implements BaseColumns, GenresColumns {
            /**
             * Get the content:// style URI for the audio genres table on the given volume.
             * 
             * @param volumeName
             *            the name of the volume to get the URI for
             * @return the URI to the audio genres table on the given volume
             */
            public static Uri getContentUri(String volumeName) {
                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/audio/genres");
            }

            /**
             * Get the content:// style URI for querying the genres of an audio file.
             * 
             * @param volumeName
             *            the name of the volume to get the URI for
             * @param audioId
             *            the ID of the audio file for which to retrieve the genres
             * @return the URI to for querying the genres for the audio file with the given the volume and
             *         audioID
             */
            public static Uri getContentUriForAudioId(String volumeName, int audioId) {
                return Uri
                        .parse(CONTENT_AUTHORITY_SLASH + volumeName + "/audio/media/" + audioId + "/genres");
            }

            /**
             * The content:// style URI for the internal storage.
             */
            public static final Uri INTERNAL_CONTENT_URI = getContentUri("internal");

            /**
             * The content:// style URI for the "primary" external storage volume.
             */
            public static final Uri EXTERNAL_CONTENT_URI = getContentUri("external");

            /**
             * The MIME type for this table.
             */
            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/genre";

            /**
             * The MIME type for entries in this table.
             */
            public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/genre";

            /**
             * The default sort order for this table
             */
            public static final String DEFAULT_SORT_ORDER = NAME;

            /**
             * Sub-directory of each genre containing all members.
             */
            public static final class Members implements AudioColumns {

                public static final Uri getContentUri(String volumeName, long genreId) {
                    return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/audio/genres/" + genreId
                            + "/members");
                }

                /**
                 * A subdirectory of each genre containing all member audio files.
                 */
                public static final String CONTENT_DIRECTORY = "members";

                /**
                 * The default sort order for this table
                 */
                public static final String DEFAULT_SORT_ORDER = TITLE_KEY;

                /**
                 * The ID of the audio file
                 * <P>
                 * Type: INTEGER (long)
                 * </P>
                 */
                public static final String AUDIO_ID = "audio_id";

                /**
                 * The ID of the genre
                 * <P>
                 * Type: INTEGER (long)
                 * </P>
                 */
                public static final String GENRE_ID = "genre_id";
            }
        }

        /**
         * Columns representing a playlist
         */
        public interface PlaylistsColumns {
            /**
             * The name of the playlist
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String NAME = "name";

            /**
             * The data stream for the playlist file
             * <P>
             * Type: DATA STREAM
             * </P>
             */
            public static final String DATA = "_data";

            /**
             * The time the file was added to the media provider Units are seconds since 1970.
             * <P>
             * Type: INTEGER (long)
             * </P>
             */
            public static final String DATE_ADDED = "date_added";

            /**
             * The time the file was last modified Units are seconds since 1970. NOTE: This is for internal
             * use by the media scanner. Do not modify this field.
             * <P>
             * Type: INTEGER (long)
             * </P>
             */
            public static final String DATE_MODIFIED = "date_modified";
        }

        /**
         * Contains playlists for audio files
         */
        public static final class Playlists implements BaseColumns, PlaylistsColumns {
            /**
             * Get the content:// style URI for the audio playlists table on the given volume.
             * 
             * @param volumeName
             *            the name of the volume to get the URI for
             * @return the URI to the audio playlists table on the given volume
             */
            public static Uri getContentUri(String volumeName) {
                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/audio/playlists");
            }

            /**
             * The content:// style URI for the internal storage.
             */
            public static final Uri INTERNAL_CONTENT_URI = getContentUri("internal");

            /**
             * The content:// style URI for the "primary" external storage volume.
             */
            public static final Uri EXTERNAL_CONTENT_URI = getContentUri("external");

            /**
             * The MIME type for this table.
             */
            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/playlist";

            /**
             * The MIME type for entries in this table.
             */
            public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/playlist";

            /**
             * The default sort order for this table
             */
            public static final String DEFAULT_SORT_ORDER = NAME;

            /**
             * Sub-directory of each playlist containing all members.
             */
            public static final class Members implements AudioColumns {
                public static final Uri getContentUri(String volumeName, long playlistId) {
                    return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/audio/playlists/" + playlistId
                            + "/members");
                }

                /**
                 * Convenience method to move a playlist item to a new location
                 * 
                 * @param res
                 *            The content resolver to use
                 * @param playlistId
                 *            The numeric id of the playlist
                 * @param from
                 *            The position of the item to move
                 * @param to
                 *            The position to move the item to
                 * @return true on success
                 */
                public static final boolean moveItem(ContentResolver res, long playlistId, int from, int to) {
                    Uri uri = MusicStore.Audio.Playlists.Members.getContentUri("external", playlistId)
                            .buildUpon().appendEncodedPath(String.valueOf(from))
                            .appendQueryParameter("move", "true").build();
                    ContentValues values = new ContentValues();
                    values.put(MusicStore.Audio.Playlists.Members.PLAY_ORDER, to);
                    return res.update(uri, values, null, null) != 0;
                }

                /**
                 * The ID within the playlist.
                 */
                public static final String _ID = "_id";

                /**
                 * A subdirectory of each playlist containing all member audio files.
                 */
                public static final String CONTENT_DIRECTORY = "members";

                /**
                 * The ID of the audio file
                 * <P>
                 * Type: INTEGER (long)
                 * </P>
                 */
                public static final String AUDIO_ID = "audio_id";

                /**
                 * The ID of the playlist
                 * <P>
                 * Type: INTEGER (long)
                 * </P>
                 */
                public static final String PLAYLIST_ID = "playlist_id";

                /**
                 * The order of the songs in the playlist
                 * <P>
                 * Type: INTEGER (long)>
                 * </P>
                 */
                public static final String PLAY_ORDER = "play_order";

                /**
                 * The default sort order for this table
                 */
                public static final String DEFAULT_SORT_ORDER = PLAY_ORDER;
            }
        }

        /**
         * Columns representing an artist
         */
        public interface ArtistColumns {
            /**
             * The artist who created the audio file, if any
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String ARTIST = "artist";

            /**
             * A non human readable key calculated from the ARTIST, used for searching, sorting and grouping
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String ARTIST_KEY = "artist_key";

            /**
             * The number of albums in the database for this artist
             */
            public static final String NUMBER_OF_ALBUMS = "number_of_albums";

            /**
             * The number of albums in the database for this artist
             */
            public static final String NUMBER_OF_TRACKS = "number_of_tracks";

            public static final String ART = "art";
        }

        /**
         * Contains artists for audio files
         */
        public static final class Artists implements BaseColumns, ArtistColumns {
            /**
             * Get the content:// style URI for the artists table on the given volume.
             * 
             * @param volumeName
             *            the name of the volume to get the URI for
             * @return the URI to the audio artists table on the given volume
             */
            public static Uri getContentUri(String volumeName) {
                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/audio/artists");
            }

            /**
             * The content:// style URI for the internal storage.
             */
            public static final Uri INTERNAL_CONTENT_URI = getContentUri("internal");

            /**
             * The content:// style URI for the "primary" external storage volume.
             */
            public static final Uri EXTERNAL_CONTENT_URI = getContentUri("external");

            /**
             * The MIME type for this table.
             */
            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/artists";

            /**
             * The MIME type for entries in this table.
             */
            public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/artist";

            /**
             * The default sort order for this table
             */
            public static final String DEFAULT_SORT_ORDER = ARTIST_KEY;

            /**
             * Sub-directory of each artist containing all albums on which a song by the artist appears.
             */
            public static final class Albums implements AlbumColumns {
                public static final Uri getContentUri(String volumeName, long artistId) {
                    return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/audio/artists/" + artistId
                            + "/albums");
                }
            }
        }

        /**
         * Columns representing an album
         */
        public interface AlbumColumns {

            /**
             * The id for the album
             * <P>
             * Type: INTEGER
             * </P>
             */
            public static final String ALBUM_ID = "album_id";

            /**
             * The album on which the audio file appears, if any
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String ALBUM = "album";

            /**
             * The artist whose songs appear on this album
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String ARTIST = "artist";

            /**
             * The number of songs on this album
             * <P>
             * Type: INTEGER
             * </P>
             */
            public static final String NUMBER_OF_SONGS = "numsongs";

            /**
             * This column is available when getting album info via artist, and indicates the number of songs
             * on the album by the given artist.
             * <P>
             * Type: INTEGER
             * </P>
             */
            public static final String NUMBER_OF_SONGS_FOR_ARTIST = "numsongs_by_artist";

            /**
             * The year in which the earliest songs on this album were released. This will often be the same
             * as {@link #LAST_YEAR}, but for compilation albums they might differ.
             * <P>
             * Type: INTEGER
             * </P>
             */
            public static final String FIRST_YEAR = "minyear";

            /**
             * The year in which the latest songs on this album were released. This will often be the same as
             * {@link #FIRST_YEAR}, but for compilation albums they might differ.
             * <P>
             * Type: INTEGER
             * </P>
             */
            public static final String LAST_YEAR = "maxyear";

            /**
             * A non human readable key calculated from the ALBUM, used for searching, sorting and grouping
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String ALBUM_KEY = "album_key";

            /**
             * Cached album art.
             * <P>
             * Type: TEXT
             * </P>
             */
            public static final String ALBUM_ART = "album_art";
        }

        /**
         * Contains artists for audio files
         */
        public static final class Albums implements BaseColumns, AlbumColumns {
            /**
             * Get the content:// style URI for the albums table on the given volume.
             * 
             * @param volumeName
             *            the name of the volume to get the URI for
             * @return the URI to the audio albums table on the given volume
             */
            public static Uri getContentUri(String volumeName) {
                return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName + "/audio/albums");
            }

            /**
             * The content:// style URI for the internal storage.
             */
            public static final Uri INTERNAL_CONTENT_URI = getContentUri("internal");

            /**
             * The content:// style URI for the "primary" external storage volume.
             */
            public static final Uri EXTERNAL_CONTENT_URI = getContentUri("external");

            /**
             * The MIME type for this table.
             */
            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/albums";

            /**
             * The MIME type for entries in this table.
             */
            public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/album";

            /**
             * The default sort order for this table
             */
            public static final String DEFAULT_SORT_ORDER = ALBUM_KEY;
        }
    }

    /**
     * Uri for querying the state of the media scanner.
     */
    public static Uri getMediaScannerUri() {
        return Uri.parse(CONTENT_AUTHORITY_SLASH + "none/media_scanner");
    }

    /**
     * Name of current volume being scanned by the media scanner.
     */
    public static final String MEDIA_SCANNER_VOLUME = "volume";

    /**
     * Name of the file signaling the media scanner to ignore media in the containing directory and its
     * subdirectories. Developers should use this to avoid application graphics showing up in the Gallery and
     * likewise prevent application sounds and music from showing up in the Music app.
     */
    public static final String MEDIA_IGNORE_FILENAME = ".nomedia";

    /**
     * Get the media provider's version. Applications that import data from the media provider into their own
     * caches can use this to detect that the media provider changed, and reimport data as needed. No other
     * assumptions should be made about the meaning of the version.
     * 
     * @param context
     *            Context to use for performing the query.
     * @return A version string, or null if the version could not be determined.
     */
    public static String getVersion(Context context) {
        Cursor c = context.getContentResolver().query(Uri.parse(CONTENT_AUTHORITY_SLASH + "none/version"),
                null, null, null, null);
        if (c != null) {
            try {
                if (c.moveToFirst()) {
                    return c.getString(0);
                }
            } finally {
                c.close();
            }
        }
        return null;
    }

    /**
     * Streaming setting info for OMA.
     * 
     * @hide
     */
    public static final class Streaming {

        /**
         * Key for oma rtsp setting. All this will be stored in Settings.db
         * 
         * @hide
         */
        public interface OmaRtspSettingColumns {
            /**
             * User displayable name for Streaming settings. <br>
             * Type: TEXT
             */
            public static final String NAME = "mtk_rtsp_name";
            /**
             * Allows application settings to be binded to this specific RTSP setting. <br>
             * Type: TEXT
             */
            public static final String PROVIDER_ID = "mtk_rtsp_provider_id";
            /**
             * Logical proxy ID for the RTSP proxy to use. To avoid confusion with other proxies, streaming
             * should use a separate logical proxy (PXLOGICAL) containing only one physical proxy
             * (PXPHYSICAL). It conrrespondes to the proxyid of apn setting. <br>
             * Type: TEXT
             */
            public static final String TO_PROXY = "mtk_rtsp_to_proxy";
            /**
             * Required if direct use of Network Access Point supported. It conrespondes to the napid of apn
             * setting. <br>
             * Type: TEXT
             */
            public static final String TO_NAPID = "mtk_rtsp_to_napid";
            /**
             * Maximum sustainable bandwidth for all transfer media, in bits per second, indicating the
             * maximum media data throughput in the network. The default value is product-specific. If
             * transfer medium specific bandwidth values are used, this value is the absolute maximum value
             * for all media. <br>
             * Type: TEXT
             */
            public static final String MAX_BANDWIDTH = "mtk_rtsp_max_bandwidth";
            /**
             * Network performance characteristics for a transfer medium. The NETINFO parameter defines the
             * performance the client should expect for audio/video streaming, and may differ from the
             * theoretical network capabilities.
             * 
             * The parameters defined for NAPDEF characteristics are not sufficient for a number of reasons:
             * The actual transfer medium and hence the bitrate used may vary even when the same NAP is used,
             * while NAPDEF only defines a single bandwidth value. For example, even if a network supports
             * WCDMA, only GSM coverage may be currently available. NAPDEF/BEARER also does not differentiate
             * between GSM-GPRS and EDGE-GPRS, but their performance is different. Finally, the operator may
             * desire to limit the bandwidth used for streaming to a fraction of the total bandwidth
             * available. <br>
             * Type: TEXT
             */
            public static final String NETINFO = "mtk_rtsp_netinfo";
            /**
             * Minimum UDP port number used for media data traffic (RTP). The default value is
             * product-specific. The value has to be even. <br>
             * Type: TEXT
             */
            public static final String MIN_UDP_PORT = "mtk_rtsp_min_udp_port";
            /**
             * Maximum UDP port number used for media data traffic (RTP). The default value is
             * product-specific. The value must be at least MIN-UDP-PORT + 5 to have enough ports for three
             * media streams (audio, video, timed text), preferably much higher. <br>
             * Type: TEXT
             */
            public static final String MAX_UDP_PORT = "mtk_rtsp_max_udp_port";
            /**
             * The sim card id. <br>
             * Type: INTEGER
             */
            public static final String SIM_ID = "mtk_rtsp_sim_id";
        }

        /**
         * Contains all oma rtsp setting. Generally, it only has one row.
         * 
         * @hide
         */
        public static final class OmaRtspSetting implements OmaRtspSettingColumns {
            /**
             * The content:// style URI for the oma rts setting.
             */
            public static final Uri CONTENT_URI = Uri.parse(CONTENT_AUTHORITY_SLASH
                    + "internal/streaming/omartspsetting");
            /**
             * The MIME type for this table.
             */
            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/omartspsetting";

        }

        /**
         * Keys for streaming settings. Oma has defined many keys for streamign, so here we just define some
         * other keys.
         * 
         * @hide
         */
        public interface SettingColumns {
            /**
             * Whether enable rtsp proxy or not.
             */
            public static final String RTSP_PROXY_ENABLED = "mtk_rtsp_proxy_enabled";
            /**
             * The rtsp proxy host. <br>
             * Type: TEXT
             */
            public static final String RTSP_PROXY_HOST = "mtk_rtsp_proxy_host";
            /**
             * The rtsp proxy port <br>
             * Type: INTEGER
             */
            public static final String RTSP_PROXY_PORT = "mtk_rtsp_proxy_port";
            /**
             * Whether enable http proxy or not.
             */
            public static final String HTTP_PROXY_ENABLED = "mtk_http_proxy_enabled";
            /**
             * The http proxy host. <br>
             * Type: TEXT
             */
            public static final String HTTP_PROXY_HOST = "mtk_http_proxy_host";
            /**
             * The http proxy port <br>
             * Type: INTEGER
             */
            public static final String HTTP_PROXY_PORT = "mtk_http_proxy_port";
        }

        public static final class Setting implements OmaRtspSettingColumns, SettingColumns {

        }
    }

    /**
     * Columns for Drm media files.
     * 
     * @hide
     */
    public interface DrmColumns {
        // should be synced with MediaColumns.IS_DRM
        // here do not delete it just for compatibility
        /**
         * <br>
         * Type: INTEGER (boolean)
         */
        public static final String IS_DRM = "is_drm";
        /**
         * <br>
         * Type: TEXT
         */
        public static final String DRM_CONTENT_URI = "drm_content_uri";
        /**
         * <br>
         * Type: INTEGER (numeric)
         */
        public static final String DRM_OFFSET = "drm_offset";
        /**
         * <br>
         * Type: INTEGER (numeric)
         */
        public static final String DRM_DATALEN = "drm_dataLen";
        /**
         * <br>
         * Type: TEXT
         */
        public static final String DRM_RIGHTS_ISSUER = "drm_rights_issuer";
        /**
         * <br>
         * Type: TEXT
         */
        public static final String DRM_CONTENT_NAME = "drm_content_name";
        /**
         * <br>
         * Type: TEXT
         */
        public static final String DRM_CONTENT_DESCRIPTION = "drm_content_description";
        /**
         * <br>
         * Type: TEXT
         */
        public static final String DRM_CONTENT_VENDOR = "drm_content_vendor";
        /**
         * <br>
         * Type: TEXT
         */
        public static final String DRM_ICON_URI = "drm_icon_uri";
        /**
         * <br>
         * Type: INTEGER (numeric)
         */
        public static final String DRM_METHOD = "drm_method";
    }

}
